package com.hzxy.yiyid.web.tool;

import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class JacksonTool {
	
	private static final Logger logger = LoggerFactory.getLogger(JacksonTool.class);
	/**
	 * jackson 中的objectMapper，writeValueAsString以及readValue是线程安全的
	 * 所以可以全局new一个static的实例
	 */
	private static ObjectMapper mapper;
	static {
		mapper = new ObjectMapper();
		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		mapper.configure(Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
	}
	
	/*
	 * @Author RAICOM2023
	 * @Description //java bean 转换为json string
	 * @Date 17:27 2023/5/1
	 * @Param [object]
	 * @return java.lang.String
	 **/
	public static String bean2Json(Object object) {
		try {
			return mapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			logger.error(e.getMessage(), e);
		}
		return null;
	}
	
	/*
	 * @Author RAICOM2023
	 * @Description //json string 转换为java bean（简单类 类数组）
	 * @Date 17:28 2023/5/1
	 * @Param [jsonStr, objClass]
	 * @return T
	 **/
	public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
		try {
			return mapper.readValue(jsonStr, objClass);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		}
		return null;
	}
	
	/*
	 * @Author RAICOM2023
	 * @Description //返回结果转jsonNode
	 * @Date 17:28 2023/5/1
	 * @Param [fromValue]
	 * @return T
	 **/
	public static <T extends JsonNode> T value2Tree(Object fromValue) {
		return mapper.valueToTree(fromValue);
	}
	
	/*
	 * @Author RAICOM2023
	 * @Description //返回结果转jsonNode
	 * @Date 17:28 2023/5/1
	 * @Param [fromValue]
	 * @return com.fasterxml.jackson.databind.JsonNode
	 **/
	public static JsonNode value2Tree(String fromValue) {
		try {
			return mapper.readTree(fromValue);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/*
	 * @Author RAICOM2023
	 * @Description //JsonNode 转 java bean
	 * @Date 17:28 2023/5/1
	 * @Param [n, valueType]
	 * @return T
	 **/
	public static <T> T tree2Value(TreeNode n, Class<T> valueType) {
		try {
			return mapper.treeToValue(n, valueType);
		} catch (JsonProcessingException e) {
			logger.error(e.getMessage(), e);
		}
		return null;
	}
	
	public static Map<String, Object> json2Map(Object obj) {
		String json;
		if (null == obj) {
			return null;
		} else if (obj instanceof String) {
			json = obj.toString();
		} else {
			json = bean2Json(obj);
		}
		if (StringUtils.isBlank(json)) return null;
		JavaType javaType = mapper.getTypeFactory().constructParametricType(HashMap.class, String.class, Object.class);
		try {
			return mapper.readValue(json, javaType);
		} catch (Exception e) {
			logger.error("json字符串转换成hashMap出错", e);
			return null;
		}
	}
	
	public static <T> T map2Value(Map<?, ?> map, Class<T> tClass) {
		try {
			return mapper.convertValue(map, tClass);
		} catch (IllegalArgumentException e) {
			logger.error("map 转换为 {} 出错", tClass.getName(), e);
		}
		return null;
	}
}
